using System;
using System.Collections.Generic;
using System.IO;
using LetsDoIt.Common;
using System.Xml.Serialization;

namespace LetsDoIt.BO
{
    /// <summary>
    /// factory class used for storing trash points locally
    /// </summary>
	public class WastesLocalFactory
	{
		private static string caseStoreFolder;
        /// <summary>
        /// storage path
        /// </summary>
        /// <returns></returns>
		public static string CasesStorePath()
		{
			return caseStoreFolder;
		}

		static WastesLocalFactory()
		{
			caseStoreFolder = Path.Combine(Utils.Utils.ApplicationPath(), FileSystemNames.CASES_FOLDER);
			if (!Directory.Exists(caseStoreFolder))
				Directory.CreateDirectory(caseStoreFolder);
		}


        /// <summary>
        /// Check if there are cases stored localy
        /// </summary>
        /// <returns>true if there are cases stored localy</returns>
        public static bool HasCases()
        {
            return Directory.GetFiles(CasesStorePath(), "*.xml").Length > 0;
        }

        /// <summary>
        /// Generate a new case (trash point) ID
        /// </summary>
        /// <returns></returns>
		public static string GetNewCaseID()
		{
			string newId = Guid.NewGuid().ToString();
			while (File.Exists(Path.Combine(CasesStorePath(), newId)))
			{
				newId = Guid.NewGuid().ToString();
			}
			return newId;
		}

        /// <summary>
        /// Save a case (trash point) locally
        /// </summary>
        /// <param name="caseinfo">case info object</param>
        /// <returns>true if succesful</returns>
		public static bool SaveLocalCase(CaseInfo caseinfo)
		{
            //check for picture files
            List<string> lstPics = new List<string>();
            foreach (string picture in caseinfo.Pictures)
            {
                string pictureFile = Path.Combine(CasesStorePath(), picture);
                if (File.Exists(pictureFile))
                {
                    lstPics.Add(picture);
                }
            }
            caseinfo.Pictures = lstPics;
            //
			string filePath = Path.Combine(CasesStorePath(), caseinfo.ID + ".xml");
			if (File.Exists(filePath))
				File.Delete(filePath);
			using (FileStream fs = File.Create(filePath))
			{
				XmlSerializer ser = new XmlSerializer(typeof(CaseInfo));
				ser.Serialize(fs, caseinfo);
			}
            //
			return true;
		}

        /// <summary>
        /// Load all local cases from local case folder
        /// </summary>
        /// <returns>list of case info objects</returns>
		public static List<CaseInfo> LoadLocalCases()
		{
			List<CaseInfo> list = new List<CaseInfo>();
			//
			foreach (string filePath in Directory.GetFiles(CasesStorePath(), "*.xml"))
			{
				CaseInfo result;
				using (FileStream fs = File.OpenRead(filePath))
				{
					XmlSerializer ser = new XmlSerializer(typeof(CaseInfo));
					result = ser.Deserialize(fs) as CaseInfo;
				}
				if(result!=null)
					list.Add(result);
			}
			list.Sort(CompareCaseByDate);
			list.Reverse();
			return list;
		}

		private static int CompareCaseByDate(CaseInfo x, CaseInfo y)
		{
			return x.CaseDateTime.CompareTo(y.CaseDateTime);
		}

        /// <summary>
        /// Loads individual case by ID
        /// </summary>
        /// <param name="id">case id</param>
        /// <returns>case info object</returns>
		public static CaseInfo LoadLocalCase(string id)
		{
			CaseInfo result = null;
			string filePath = Path.Combine(CasesStorePath(), id + ".xml");
			if (File.Exists(filePath))
			{
				using (FileStream fs = File.OpenRead(filePath))
				{
					XmlSerializer ser = new XmlSerializer(typeof(CaseInfo));
					result = ser.Deserialize(fs) as CaseInfo;
				}
			}
			return result;
		}


        /// <summary>
        /// Delete a case by ID
        /// </summary>
        /// <param name="caseId">case id</param>
        public static bool DeleteLocalCase(string caseId)
        {
            bool hasDeleted = false;
            foreach (string filePath in Directory.GetFiles(WastesLocalFactory.CasesStorePath(), caseId + "*.*"))
            {
                File.Delete(filePath);
                hasDeleted = true;
            }
            return hasDeleted;
        }
	}
}